use clap::{arg, command};
use reder::{crc32_, md5, sha1};
use std::fs::File;
use std::io::{stdin, stdout, IsTerminal};
use std::{env, io};

fn main() {
    let matches = command!()
        .arg(
            arg!(-'e' --"encode" <encode> "set the encode format")
                .required(false)
                .value_parser(["crc32", "md5", "sha1"]),
        )
        .arg(
            arg!(-'f' --"file" <file>  "set the input file")
                .required(false)
                .value_parser(clap::builder::NonEmptyStringValueParser::new()),
        )
        .arg(arg!(-'o' --"output" <output> "set the out put file").required(false))
        .get_matches();

    let mut stdin = stdin();
    let mut stdout = stdout();
    // let is_tty = stdin.is_terminal();
    let f = matches.get_one::<String>("file");
    let e = matches
        .get_one::<String>("encode")
        .expect("parser encode format failed");
    let mut ifile: File;
    let mut ofile: File;
    let o = matches.get_one::<String>("output");

    let dest: &mut dyn io::Write = match o {
        None => &mut stdout,
        Some(ref a) => {
            ofile = File::create(a).expect("output file open failed");
            &mut ofile
        }
    };
    let src: &mut dyn io::Read = match f {
        None => {
            if stdin.is_terminal() {
                println!("dont support input by manual type");
                return;
            }
            &mut stdin
        }
        Some(ref a) => {
            ifile = File::open(a).unwrap();
            &mut ifile
        }
    };
    match &e as &str {
        "crc32" => {
            crc32_::encode(&mut *src, &mut *dest);
        }
        "md5" => md5::encode(&mut *src, &mut *dest),
        "sha1" => sha1::encode(&mut *src, &mut *dest),
        _ => {}
    }
}
